package com.sdy.dcsb.web.controller.inboundservice.util;

import com.sdy.common.utils.StringUtil;
import com.sdy.dcsb.biz.constants.RedisConstants;
import com.sdy.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Component;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.Lock;

/**
 * <p>
 * 流控工具类
 * </p>
 *
 * @author fb
 * @since 2019/10/31
 */
@Component
public class FlowUtil {

    @Autowired
    private RedisService redisService;
    @Autowired
    private RedisLockRegistry redisLockRegistry;

    private static DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");

    public boolean doCheckFrequency(String name, String reqCountMax) {

        Lock lock = redisLockRegistry.obtain(RedisConstants.LOCK_SERVICE_DAY);
        if(lock.tryLock()) {
            try {
                if(!timeLimited()) {
                    redisService.delRegx(RedisConstants.REDIS_SERVICE_COUNT + "*");
                }
            } finally {
                lock.unlock();
            }
        }

        // 调用次数类型转换
        Long reqCountMaxLong = Long.valueOf(reqCountMax);
        Long count = redisService.incr(RedisConstants.REDIS_SERVICE_COUNT + name);
        if (count > reqCountMaxLong) {
            redisService.incr(RedisConstants.REDIS_SERVICE_COUNT + name, -1L);
            return false;
        }else {
            return true;
        }
    }

    /**
     * 用来刷新隔天来访问的次数
     * @return
     */
    private boolean timeLimited() {
        String time = dateFormat.format(new Date());
        String dayTime = redisService.get(RedisConstants.REDIS_SERVICE_DAY, String.class);
        if (StringUtil.isBlank(dayTime)) {
            redisService.set(RedisConstants.REDIS_SERVICE_DAY, time);
            return true;
        }else if(time.equals(dayTime)) {
            return true;
        }else {
            redisService.set(RedisConstants.REDIS_SERVICE_DAY, time);
            return false;
        }
    }

}
